package com.atguigu.gmall.order.listener;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.model.enums.OrderStatus;
import com.atguigu.gmall.model.enums.PaymentStatus;
import com.atguigu.gmall.model.enums.ProcessStatus;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.mq.mqconst.MqDeadLetterConst;
import com.atguigu.gmall.mq.mqconst.MqOrderConst;
import com.atguigu.gmall.mq.mqconst.MqWareConst;
import com.atguigu.gmall.order.service.OrderService;
import com.atguigu.gmall.payment.client.PaymentFeignClient;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;

@Component
public class OrderListener {

    @Autowired
    private OrderService orderService;

    @Autowired
    private PaymentFeignClient paymentFeignClient;


    @RabbitListener(queues = MqDeadLetterConst.QUEUE_DEAD)
    public void messageDead(Message message, Channel channel, Long orderId) throws IOException {
        OrderInfo orderInfo = orderService.getOrderById(orderId);
        String orderStatus = orderInfo.getOrderStatus();
        if (OrderStatus.UNPAID.name().equals(orderStatus)) {
            Boolean checkPay = paymentFeignClient.checkPayStatusRemote(orderInfo.getOutTradeNo()).getData();
            if (checkPay) {
                Boolean closePay = paymentFeignClient.closePay(orderInfo.getOutTradeNo()).getData();
                if (!closePay) {
                    return;
                }
            }
            orderService.updateOrderStatus(orderId.toString(), OrderStatus.CLOSED.name(), ProcessStatus.CLOSED.name());
            paymentFeignClient.closePaymentInfo(orderInfo.getOutTradeNo());

        }
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }


    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqOrderConst.QUEUE_ORDER, durable = "true", autoDelete = "false"),
            exchange = @Exchange(value = MqOrderConst.EXCHANGE_ORDER, durable = "true", autoDelete = "false"),
            key = {MqOrderConst.ROUTING_KEY_ORDER}
    ))
    public void messageOrder(Message message, Channel channel, Long orderId) throws IOException {
        try {
            if (orderId != null) {
                OrderInfo orderInfo = orderService.getOrderById(orderId);
                orderInfo.setOrderStatus(PaymentStatus.PAID.name());
                orderInfo.setProcessStatus(ProcessStatus.PAID.name());
                orderService.saveOrderById(orderInfo);

                //通知库存 减去卖出的库存
                orderService.notifyWareSystemToDeliver(orderId);
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            Boolean redelivered = message.getMessageProperties().getRedelivered();
            if (redelivered) {
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
            } else {
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            }
        }

    }


    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqWareConst.QUEUE_WARE_ORDER, durable = "true", autoDelete = "false"),
            exchange = @Exchange(value = MqWareConst.EXCHANGE_WARE_ORDER, durable = "true", autoDelete = "false"),
            key = {MqWareConst.ROUTING_KEY_WARE_ORDER}
    ))
    public void messageWareOrder(String messageJson, Message message, Channel channel) {
        Map<String, String> resultMap = JSONObject.parseObject(messageJson, Map.class);
        String orderId = resultMap.get("orderId");
        String status = resultMap.get("status");
        if ("DEDUCTED".equals(status)) {
            orderService.updateOrderStatus(orderId, OrderStatus.WAITING_DELEVER.name(), ProcessStatus.WAITING_DELEVER.name());
        }else if("OUT_OF_STOCK".equals(status)){
            orderService.updateOrderStatus(orderId, ProcessStatus.STOCK_EXCEPTION.name(), ProcessStatus.STOCK_EXCEPTION.name());
        }
    }
}
